/**
 * 
 */
package com.yi.model.db.mongo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.mongodb.WriteResult;
import com.yi.model.objects.DBDefinitions;

/**
 * @author yilo
 * 
 */
public class MongoDBHelper {

	private MongoConnection _conn;

	private final int numberOfPage = 10;

	public MongoConnection getConn() {
		return _conn;
	}

	public void setConn(MongoConnection _conn) {
		this._conn = _conn;
	}

	public String addEntity(String collName, DBObject entity)
			throws MongoException {
		DBCollection currColl = getConn().getCollection(collName);
		DBObject exist = currColl.findOne(new BasicDBObject(
				DBDefinitions.col_name, entity.get(DBDefinitions.col_name)));
		if (exist == null) {
			currColl.insert(entity);
			return entity.get(DBDefinitions.col_id).toString();
		}
		return exist.get(DBDefinitions.col_id).toString();
	}

	public DBObject viewEntity(String collName, String colName, String colVal)throws MongoException{
		DBCursor cursor = getConn().getCollection(collName).find(
				new BasicDBObject(colName, colVal));
		return cursor.next();
	}
	
	public DBObject viewEntityById(String collName, String entityId)
			throws MongoException {
		DBCursor cursor = getConn().getCollection(collName).find(
				new BasicDBObject(DBDefinitions.col_id, entityId));
		return cursor.next();
	}
	
	public DBObject viewEntityByName(String collName, String entityName)
			throws MongoException {
		DBCursor cursor = getConn().getCollection(collName).find(
				new BasicDBObject(DBDefinitions.col_name, entityName));
		return cursor.next();
	}

	public void removeEntityById(String collName, String entityId)
			throws MongoException {
		getConn().getCollection(collName).remove(
				viewEntityById(collName, entityId));
	}

	public void updateEntity(String collName, DBObject entity)
			throws MongoException {
		getConn().getCollection(collName).updateMulti(
				new BasicDBObject(DBDefinitions.col_id,
						entity.get(DBDefinitions.col_id)), entity);
	}

	public List<DBObject> findEntities(final String collName,
			final int pageNumber) {

		return findSpecicialEntities(collName, pageNumber, null);
	}

	public List<DBObject> findSpecicialEntities(final String collName,
			final int pageNumber, DBObject query) {
		DBCursor cursor = null;
		if (query == null) {
			if (pageNumber == 0)
				cursor = getConn().getCollection(collName).find()
						.sort(new BasicDBObject(DBDefinitions.col_created, -1));
			else
				cursor = getConn().getCollection(collName).find()
						.sort(new BasicDBObject(DBDefinitions.col_created, -1))
						.limit(numberOfPage * pageNumber);
		} else {
			if (pageNumber == 0)
				cursor = getConn().getCollection(collName).find(query)
						.sort(new BasicDBObject(DBDefinitions.col_created, -1));
			else
				cursor = getConn().getCollection(collName).find(query)
						.sort(new BasicDBObject(DBDefinitions.col_created, -1))
						.limit(numberOfPage * pageNumber);

		}
		List<DBObject> matches = new ArrayList<DBObject>();
		while (cursor.hasNext()) {
			matches.add(cursor.next());
		}
		return matches;
	}

	public void createCollectionByName(final String collName) {
		DB db = getConn().getDb();
		if (!db.isAuthenticated())
			db.authenticate(getConn().getUserName(), getConn().getPassword()
					.toCharArray());
		db.createCollection(collName, null);
	}

	public boolean checkAccessRight(final String collName, final String id,
			final String objName, final String operName) throws MongoException {
		boolean canAccess = false;
		DBObject queried = getConn().getCollection(collName).findOne(
				new BasicDBObject(DBDefinitions.col_id, id));
		if (queried == null)
			return canAccess;
		if (queried.get(DBDefinitions.col_permission) != null) {
			Map<String, String> permissions = (Map<String, String>) queried
					.get(DBDefinitions.col_permission);
			// *:*
			if (permissions.containsKey("*")
					&& permissions.get("*").contains("*"))
				return true;
			// *:operName
			else if (permissions.containsKey("*")
					&& permissions.get("*").contains(operName))
				return true;
			// objName:operName
			else if (permissions.containsKey(objName)) {
				if (permissions.get(objName).contains(operName))
					return true;
				return canAccess;
			}
			//
			else
				return canAccess;

		} else
			return canAccess;

	}

}
